#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<memory>
#include<mutex>
using namespace std;

//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	int* array1 = new int[10];
//	try
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Divide(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array1 << endl;
//		delete[] array1;
//		throw; //重新抛出
//	}
//	cout << "delete []" << array1 << endl;
//	delete[] array1;
//}
//int main()
//{
//	while (1)
//	{
//		try
//		{
//			Func();
//		}
//		catch (const char* errmsg)
//		{
//			cout << errmsg << endl;
//		}
//		catch (const exception& e)
//		{
//			cout << e.what() << endl;
//		}
//		catch (...)
//		{
//			cout << "未知异常" << endl;
//		}
//	}
//	return 0;
//}

//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	int* array1 = new int[10];
//	int* array2 = new int[10]; // 如果array2抛异常呢
//	try
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Divide(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array1 << endl;
//		cout << "delete []" << array2 << endl;
//		delete[] array1;
//		delete[] array2;
//		throw; // 异常重新抛出，捕获到什么抛出什么
//	}
//	cout << "delete []" << array1 << endl;
//	delete[] array1;
//	cout << "delete []" << array2 << endl;
//	delete[] array2;
//}
//int main()
//{
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//	return 0;
//}


//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//template<class T>
//class SmartPtr
//{
//public:
//	SmartPtr(T* ptr)
//		:_ptr(ptr)
//	{}
//	~SmartPtr()
//	{
//		cout << "delete[]" << _ptr << endl;
//		delete[] _ptr;
//	}
//	//重载运算符，模拟指针的行为，方便访问资源
//	T& operator*()
//	{
//		return *_ptr;
//	}
//	T* operator->()
//	{
//		return _ptr;
//	}
//	T& operator[](size_t i)
//	{
//		return _ptr[i];
//	}
//private:
//	T* _ptr;
//};
//void Func()
//{
//	// 这里使用RAII的智能指针类管理new出来的数组以后，程序简单多了
//	SmartPtr<int> sp1 = new int[10];
//	SmartPtr<int> sp2 = new int[10];
//	for (size_t i = 0; i < 10; i++)
//	{
//		sp1[i] = sp2[i] = i;
//	}
//	int len, time;
//	cin >> len >> time;
//	cout << Divide(len, time) << endl;
//}
//int main()
//{
//	while (1)
//	{
//		try
//		{
//			Func();
//		}
//		catch (const char* errmsg)
//		{
//			cout << errmsg << endl;
//		}
//		catch (const exception& e)
//		{
//			cout << e.what() << endl;
//		}
//		catch (...)
//		{
//			cout << "未知异常" << endl;
//		}
//	}
//	return 0;
//}


//struct Date
//{
//	int _year;
//	int _month;
//	int _day;
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{}
//	~Date()
//	{
//		cout << "~Date()" << endl;
//	}
//};
//int main()
//{
//	//auto_ptr<Date> ap1(new Date);
//	//// 拷贝时，管理权限转移，被拷贝对象ap1悬空
//	//auto_ptr<Date> ap2(ap1);
//	//// 空指针访问，ap1对象已经悬空
//	//// ap1->_year++;
//
//	//unique_ptr<Date> up1(new Date);
//	//// 不支持拷贝
//	//// unique_ptr<Date> up2(up1);
//	//// 支持移动，但是移动后up1也悬空，所以使用移动要谨慎
//	//unique_ptr<Date> up3(move(up1));
//
//	shared_ptr<Date> sp1(new Date);
//	// 支持拷贝
//	shared_ptr<Date> sp2(sp1);
//	shared_ptr<Date> sp3(sp2);
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//	// 支持移动，但是移动后sp1也悬空，所以使用移动要谨慎
//	shared_ptr<Date> sp4(move(sp1));
//	return 0;
//}

//struct Date
//{
//	int _year;
//	int _month;
//	int _day;
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{}
//	~Date()
//	{
//		cout << "~Date()" << endl;
//	}
//};
//template<class T>
//void DeleteArrayFunc(T* ptr)
//{
//	delete[] ptr;
//}
//template<class T>
//class DeleteArray
//{
//public:
//	void operator()(T* ptr)
//	{
//		delete[] ptr;
//	}
//};
//class Fclose
//{
//public:
//	void operator()(FILE* ptr)
//	{
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//	}
//};
//int main()
//{
//	// 这样实现程序会崩溃
//	// unique_ptr<Date> up1(new Date[10]);
//	// shared_ptr<Date> sp1(new Date[10]);
//	// 解决方案1
//	// 因为new[]经常使用，所以unique_ptr和shared_ptr
//	// 实现了一个特化版本，这个特化版本析构时用的delete[]
//	unique_ptr<Date[]> up1(new Date[5]);
//	shared_ptr<Date[]> sp1(new Date[5]);
//	// 解决方案2
//	// 仿函数对象做删除器
//	// unique_ptr<Date, DeleteArray<Date>> up2(new Date[5], DeleteArray<Date>());
//	// unique_ptr和shared_ptr支持删除器的方式有所不同
//	// unique_ptr是在类模板参数支持的，shared_ptr是构造函数参数支持的
//	// 这里没有使用相同的方式还是挺坑的
//	// 使用仿函数unique_ptr可以不在构造函数传递，因为仿函数类型构造的对象直接就可以调用
//	// 但是下面的函数指针和lambda的类型不可以
//	unique_ptr<Date, DeleteArray<Date>> up2(new Date[5]);
//	shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());
//
//	// 函数指针做删除器
//	unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
//	shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);
//
//	// lambda表达式做删除器
//	auto delArrOBJ = [](Date* ptr) {delete[] ptr; };
//	// decltype可以自动推导参数的类型
//	unique_ptr<Date, decltype(delArrOBJ)> up4(new Date[5], delArrOBJ);
//	shared_ptr<Date> sp4(new Date[5], delArrOBJ);
//
//	// 实现其他资源管理的删除器
//	shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
//	shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//		});
//	return 0;
//}
//int main()
//{
//	shared_ptr<Date> sp1(new Date(2025, 1, 1));
//	shared_ptr<Date> sp2 = make_shared<Date>(2025, 1, 1);
//	auto sp3 = make_shared<Date>(2025, 1, 1);
//	shared_ptr<Date> sp4;
//
//	// if (sp1.operator bool())
//	if (sp1)
//		cout << "sp1 is not nullptr" << endl;
//	if (!sp4)
//		cout << "sp4 is nullptr" << endl;
//
//	// 报错，不支持隐式类型转换
//	/*shared_ptr<Date> sp5 = new Date(2024, 9, 11);
//	unique_ptr<Date> sp6 = new Date(2024, 9, 11);*/
//	return 0;
//}

//#include "shared_ptr.h"
//struct Date
//{
//	int _year;
//	int _month;
//	int _day;
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//	}
//	~Date()
//	{
//		cout << "~Date()" << endl;
//	}
//};
//int main()
//{
//	MY::auto_ptr<Date> ap1(new Date);
//	// 拷贝时，管理权限转移，被拷贝对象ap1悬空
//	MY::auto_ptr<Date> ap2(ap1);
//	// 空指针访问，ap1对象已经悬空
//	//ap1->_year++;
//	MY::unique_ptr<Date> up1(new Date);
//	// 不支持拷贝
//	//unique_ptr<Date> up2(up1);
//	// 支持移动，但是移动后up1也悬空，所以使用移动要谨慎
//	MY::unique_ptr<Date> up3(move(up1));
//
//	MY::shared_ptr<Date> sp1(new Date);
//	// 支持拷贝
//	MY::shared_ptr<Date> sp2(sp1);
//	MY::shared_ptr<Date> sp3(sp2);
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//
//	return 0;
//}

//struct ListNode
//{
//	int _data;
//	/*std::shared_ptr<ListNode> _next;
//	std::shared_ptr<ListNode> _prev;*/
//
//	// 这里改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
//	// 不增加n2的引用计数，不参与资源释放的管理，就不会形成循环引用了
//	std::weak_ptr<ListNode> _next;
//	std::weak_ptr<ListNode> _prev;
//	~ListNode()
//	{
//		cout << "~ListNode()" << endl;
//	}
//};
//int main()
//{
//	// 循环引用 -- 内存泄露
//	std::shared_ptr<ListNode> n1(new ListNode);
//	std::shared_ptr<ListNode> n2(new ListNode);
//
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	n1->_next = n2;
//	n2->_prev = n1;
//
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	// weak_ptr不支持管理资源，不支持RAII
//	// weak_ptr是专门绑定shared_ptr，不增加他的引用计数，作为一些场景的辅助管理
//	//std::weak_ptr<ListNode> wp(new ListNode);
//	
//	return 0;
//}

//int main()
//{
//	std::shared_ptr<string> sp1(new string("111111"));
//	std::shared_ptr<string> sp2(sp1);
//	std::weak_ptr<string> wp = sp1;
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	// sp1和sp2都指向了其他资源，则weak_ptr就过期了
//	sp1 = make_shared<string>("222222");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	sp2 = make_shared<string>("333333");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//
//	wp = sp1;
//	//std::shared_ptr<string> sp3 = wp.lock();
//	auto sp3 = wp.lock();
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	*sp3 += "###";
//	cout << *sp1 << endl;
//	return 0;
//}

#include "shared_ptr.h"
struct AA
{
	int _a1 = 0;
	int _a2 = 0;
	~AA()
	{
		cout << "~AA()" << endl;
	}
};
int main()
{
	MY::shared_ptr<AA> p(new AA);
	const size_t n = 100000;
	mutex mtx;
	auto func = [&]()
		{
			for (size_t i = 0; i < n; ++i)
			{
				// 这里智能指针拷贝会++计数
				MY::shared_ptr<AA> copy(p);
				{
					unique_lock<mutex> lk(mtx);
					copy->_a1++;
					copy->_a2++;
				}
			}
		};
	thread t1(func);
	thread t2(func);
	t1.join();
	t2.join();
	cout << p->_a1 << endl;
	cout << p->_a2 << endl;
	cout << p.use_count() << endl;

	return 0;
}